#include "Game.h"
#include "util.h"
#include "Code/OgreMaxScene.hpp"
#include "Config.h"

Level::~Level(void)
{
	std::vector<Pig>::iterator it;
	for (it=pigs.begin(); it!=pigs.end(); it++)
	{
		Pig* pig = &(*it);
		delete pig;
	}
}

void Level::switchState()
{
	State* nextState=NULL;
	if(curState==NULL)
		nextState=autoState;
	if(curState==autoState) {
		nextState=manualState;
	} else if (curState==manualState) {
		nextState = targetState;
	} else if (curState==targetState) {
		nextState = flyHitState;
	} else if (curState==flyHitState) {
		nextState=manualState;
	}

	if(curState)
		curState->stateEnded();
	curState=nextState;
	curState->init();
	curState->stateStarted();
}



#define USE_XML 1

void Level::createGameObjs()
{ 
	using std::vector;
#ifdef USE_XML
	vector<GameObj*> objs = Config::getInstance()->getGameObjs();
	typedef std::vector<GameObj*>::iterator It;
	for(It it=objs.begin();it!=objs.end();++it){
		if((*it)->getType()==OT_BIRD){
			birds.push_back(*((Bird*)*it));
		}else if((*it)->getType()==OT_PIG){
			pigs.push_back(*((Pig*)*it));
		}
		else if((*it)->getType()==OT_BLOCK){
			blocks.push_back(*((Block*)*it));
		}
	}
#else
	//create pigs
	Pig* pig = 0;
	int pigNum=2;
	ASSERT(pigs.size()==0);
	for(int i=0;i<pigNum;i++){
		pig=new Pig();
		Ogre::Vector3 size(2.0, 2.0, 2.0);
		Ogre::Vector3 pos(20.0f+i*10.0f, 6.0f, 50.0f);
		Ogre::Quaternion orient(Ogre::Quaternion::IDENTITY);
		pig->init(size,pos,orient);
		pigs.push_back(*pig);
	}

	//create birds
	Bird * bird=0;
	int birdNum=4;
	ASSERT(birds.size()==0);
	for(int i=0;i<birdNum;i++){
		bird=new Bird();
		Ogre::Vector3 size(0.2, 0.2, 0.2);
		Ogre::Vector3 pos(-20.0f-i*10.0f, -6.0f, 100.0f);
		Ogre::Quaternion orient(Ogre::Quaternion::IDENTITY);
		bird->init(size,pos,orient);
		birds.push_back(*bird);
	}
#endif
	getBirdsReady();
}



void Level::createScene()
{
	//createMaterials();
	createGameObjs();
	Game * game = Game::getInstance();

//  	OgreMax::OgreMaxScene *oms = new OgreMax::OgreMaxScene;
//  	oms->Load("moun.scene",game->mWindow,0,game->mSceneMgr);

	//floor Object
	Ogre::Vector3 size = Ogre::Vector3 (2.0,0.5,2.0);
	Ogre::Entity* floor;
	Ogre::SceneNode* floornode;
	const char* levelName = "track.mesh";

	floor = game->mSceneMgr->createEntity("Floor",levelName);
	floornode = game->mSceneMgr->getRootSceneNode()->createChildSceneNode();
	floornode->attachObject(floor);
	floornode->setScale(size);
	floor->setCastShadows(false);

	char serializeCollisionName[256];
	strcpy (serializeCollisionName, levelName);
	strtok (serializeCollisionName, ".");
	strcat (serializeCollisionName, ".col");

	FILE* file = fopen (serializeCollisionName, "rb");
	if (!file) {
		// serialize the mesh so that next time loads faster
		OgreNewt::CollisionSerializer saveLevelCollision; 
		OgreNewt::CollisionPtr tmpSphape = OgreNewt::CollisionPtr(new OgreNewt::CollisionPrimitives::TreeCollision( game->mWorld, floor, true, 0 ));
		saveLevelCollision.exportCollision(tmpSphape, serializeCollisionName);
		file = fopen (serializeCollisionName, "rb");
	}

	// load level collision from serialized file
	FileHandleDataStream streamFile (file);
	OgreNewt::CollisionSerializer loadLevelCollision; 
	OgreNewt::CollisionPtr col = loadLevelCollision.importCollision(streamFile, game->mWorld);
	fclose (file);
	OgreNewt::Body* bod = new OgreNewt::Body( game->mWorld, OgreNewt::CollisionPtr(col));
	bod->attachNode( floornode );
	bod->setType(OT_GROUND);

	// set the world bound to the size of the world AABB
	Ogre::AxisAlignedBox worldAABB (bod->getAABB());
	worldAABB.getMinimum().y -= 1000.0f;
	worldAABB.getMaximum().y += 1000.0f;
	game->mWorld->setWorldSize (worldAABB.getMinimum(), worldAABB.getMaximum());

	game->mSceneMgr->setSkyDome(true,"Examples/CloudySky",5,8);

	//shadow on
	game->mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);

	// Set ambient light
	game->mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));

	// Create a light
	Ogre::Light* l = game->mSceneMgr->createLight("MainLight");
	l->setPosition(20,80,50);
	Ogre::Light* ll = game->mSceneMgr->createLight("MainLight2");
	l->setPosition(20,80,800);
	Ogre::Light* lll = game->mSceneMgr->createLight("MainLight3");
	l->setPosition(20,400,-100);
}

